/*  
* Copyright (c) 2015-2026 LeeSon Ltd. All Rights Reserved.  
* LeeSon  QQ:25901875
*/ 
package com.leeson.portal.core.listener;

import java.net.InetAddress;
import java.util.Date;
import java.util.HashMap;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;

import com.leeson.portal.core.model.OnlineMap;
import com.leeson.portal.core.service.InterfaceControl;
import com.leeson.portal.core.utils.SpringContextHelper;
import com.leeson.portal.manage.domain.Account;
import com.leeson.portal.manage.domain.LinkRecord;
import com.leeson.portal.manage.domain.LogRecord;
import com.leeson.portal.manage.service.AccountService;
import com.leeson.portal.manage.service.LinkRecordService;
import com.leeson.portal.manage.service.LogRecordService;

public class CheckOnline extends Thread{
	
	private static com.leeson.portal.core.model.Config config = com.leeson.portal.core.model.Config.getInstance();
	private static Logger log = Logger.getLogger(CheckOnline.class);
	
//	ApplicationContext ac =new ClassPathXmlApplicationContext("applicationContext.xml");
	
	ApplicationContext ac=SpringContextHelper.getApplicationContext();
	
	OnlineMap onlineMap=OnlineMap.getInstance();
	HashMap<String, String[]> onlineUserMap=onlineMap.getOnlineUserMap();
	
	private String host;
	private String username;
	
	
	String[] loginInfo;
	
	
	Long userId;
	Long recordId;
	LinkRecordService linkRecordService;
	AccountService accountService;
	LinkRecord linkRecord;
	Account account;
	String state;

	public CheckOnline(String host,String username) {
		this.host = host;
		this.username=username;
		this.loginInfo=onlineUserMap.get(host);
		
		
		
		if(config.getAuth_interface().equals("1")){
			this.userId=Long.parseLong(loginInfo[1]);
			this.recordId=Long.parseLong(loginInfo[2]);
			this.linkRecordService=(LinkRecordService) ac.getBean("linkRecordServiceImpl");
			this.linkRecord=linkRecordService.getById(recordId);
			this.accountService=(AccountService) ac.getBean("accountServiceImpl");
			this.account=accountService.getById(userId);
			this.state=account.getState();
		}
		
	}
	
	public void run() {
		if(config.getAuth_interface().equals("1")){
			if(startCheckOverTime()){
				 if(Integer.parseInt(config.getUserHeart())==1){
					 if(config.getDebug().equals("1")){
		    				log.info("开始用户心跳检测！！！！每IP检测超时次数："+config.getUserHeartCount());
		    			}
					 doCheckOnline();
	    			}
				
			}
		}else {
			 if(Integer.parseInt(config.getUserHeart())==1){
				 
				 if(config.getDebug().equals("1")){
	    				log.info("开始用户心跳检测！！！！每IP检测超时次数："+config.getUserHeartCount());
	    			}
				 doCheckOnline();
    			}
		}
		
	}

	private boolean startCheckOverTime() {
		if(config.getAuth_interface().equals("1")){
			if(config.getDebug().equals("1")){
				log.info("开始检测余额：IP:"+host+"账户"+username);
			}
			if(state.equals(String.valueOf(3))||state.equals(String.valueOf(2))){
				if(!doCheckOverTime()){
					Boolean info = InterfaceControl.Method("PORTAL_LOGINOUT",
							username, "password", host);
					if (info == true) {
						onlineMap.getOnlineUserMap().remove(host);
						if(config.getDebug().equals("1")){
		    				log.info("IP:"+host+"账户"+username+"余额不足，强制下线成功！！");
		    			}
						doLogRecord("IP:"+host+"账户"+username+"余额不足，强制下线成功！！");
					}else {
						onlineMap.getOnlineUserMap().remove(host);
						if(config.getDebug().equals("1")){
		    				log.info("IP:"+host+"账户"+username+"余额不足，强制下线???");
		    			}
						doLogRecord("IP:"+host+"账户"+username+"余额不足，强制下线???");
					}
					return false;
				}
				
			}
		}
		
		return true;
	}

	private boolean doCheckOverTime() {
		
		Date now=new Date();
		Long costTime=now.getTime()-linkRecord.getStartDate().getTime();
		Date toDate=account.getDate();
		Long haveTime=account.getTime();
		
		Long newHaveTime=haveTime-costTime;
		
		if(state.equals(String.valueOf(3))){
			if(toDate.getTime()<=now.getTime()){
				linkRecord.setEndDate(now);
				linkRecord.setTime(costTime);
				linkRecordService.update(linkRecord);
				return false;
			}
		}
		if(state.equals(String.valueOf(2))){
			if(newHaveTime<=0){
				account.setState(String.valueOf(0));
				account.setTime(newHaveTime);
				accountService.update(account);
				
				linkRecord.setEndDate(now);
				linkRecord.setTime(costTime);
				linkRecordService.update(linkRecord);
				return false;
			}
			
		}
		return true;
	}

	private void doCheckOnline() {
		boolean state = false;
		int count = 0;
		while (!state) {
			state = doPing();
			if (state) {
				if(config.getDebug().equals("1")){
    				log.info(host + "在线！！");
    			}
				
			} else {
				if(config.getDebug().equals("1")){
    				log.info(host + "超时！！");
    			}
			}
			count++;
			if (count >= Integer.parseInt(config.getUserHeartCount())) {
				if(config.getDebug().equals("1")){
    				log.info(host + "不在线！！停止计费！！发送下线请求！！");
    			}
				Boolean info = InterfaceControl.Method("PORTAL_LOGINOUT",
						username, "password", host);
				if (info == true) {
					if(config.getAuth_interface().equals("1")){
						doLinkRecord();
					}
					onlineMap.getOnlineUserMap().remove(host);
					if(config.getDebug().equals("1")){
	    				log.info(host + "强制下线成功！！");
	    			}
					doLogRecord("IP:"+host+",用户："+username+",心跳检测超时，强制下线成功!");
				}else {
					if(config.getAuth_interface().equals("1")){
						doLinkRecord();
					}
					onlineMap.getOnlineUserMap().remove(host);
					if(config.getDebug().equals("1")){
	    				log.info(host + "强制下线???");
	    			}
					doLogRecord("IP:"+host+",用户："+username+",心跳检测超时，强制下线???");
				}
				break;
			}
		}
	}

	/**
	 * 连接日志
	 * @param request
	 * @param ip
	 * @param username
	 */
	private void doLinkRecord() {
		Date now=new Date();
		linkRecord.setEndDate(now);
		Long costTime=now.getTime()-linkRecord.getStartDate().getTime();
		linkRecord.setTime(costTime);
		linkRecordService.update(linkRecord);
		
		if(config.getAuth_interface().equals("1")){
			if(state.equals(String.valueOf(3))||state.equals(String.valueOf(2))){
				Long haveTime=account.getTime();
				Long newHaveTime=haveTime-costTime;
				if(state.equals(String.valueOf(2))){
					if(newHaveTime<=0){
						account.setState(String.valueOf(0));
					}
					account.setTime(newHaveTime);
					accountService.update(account);
				}
			}
		}
		
		
	}
	
	private void doLogRecord(String info) {
		LogRecord logRecord=new LogRecord();
		Date nowDate=new Date();
		logRecord.setInfo(info);
		logRecord.setRec_date(nowDate);
		LogRecordService logRecordService=(LogRecordService) ac.getBean("logRecordServiceImpl");
		logRecordService.save(logRecord);
	}
	
	public boolean doPing() {

		boolean a = false;
		int timeOut = Integer.parseInt(config.getTimeoutSec()); // I recommend 3 seconds at least
		try {
			a = InetAddress.getByName(host).isReachable(timeOut*1000);
		} catch (Exception e) {
			// TODO Auto-generated catch block

			e.printStackTrace();
			return a;
		}
		return a;
	}

	

}
